package com.nb.java14.BlackBerry.ui;

import com.nb.java14.BlackBerry.ui.widgets.GridFieldManager;
import com.nb.java14.UI.BasicUIKeys;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;

import java.util.Enumeration;
import java.util.Vector;


/**
 * @author Nahuel Barrios.
 * @version 1.0
 * @since 20/07/2010.
 */
public class UIUtil {

	/**
	 * @param data
	 *
	 * @return
	 */
	public static GridFieldManager loadHeadersToGrid(GridFieldManager aGrid, Field[] data) {
		Vector dataVector = new Vector(data.length);
		dataVector.addElement(data);

		return loadFieldGridFrom(aGrid, dataVector);
	}

	/**
	 * Carga una grilla en base al Vector data que contiene un elemento por cada fila de la grilla, donde cada elemento es
	 * un Field[] que contiene cada Field a mostrar en cada columna de la grilla.
	 *
	 * @param aGrid
	 * @param data
	 *
	 * @return
	 */
	public static GridFieldManager loadFieldGridFrom(GridFieldManager aGrid, Vector data) {
		if (data == null || data.isEmpty())
			return null;

		if (aGrid == null)
			return null;

		Enumeration elements = data.elements();
		while (elements.hasMoreElements()) {
			Field[] fields = (Field[]) elements.nextElement();

			for (int idx = 0; idx < aGrid.getColumns(); idx++)
				aGrid.add(fields[idx]);

			for (int idx = 0; idx < aGrid.getColumns(); idx++)
				aGrid.add(new SeparatorField());
		}

		return aGrid;
	}

	/**
	 * Preparo los headers para una grilla, se le aplica un formato de texto y retorno el Field[] necesario.
	 *
	 * @param headers Un Vector con los {@link String} de los headers.
	 * @param parent
	 *
	 * @return
	 */
	public static Field[] prepareHeadersForGrid(Vector headers, MainScreen parent) {
		Field[] fields = new Field[headers.size()];

		Enumeration elements = headers.elements();
		for (int i = 0; elements.hasMoreElements(); i++) {
			LabelField lbl_header = new LabelField((String) elements.nextElement(), Field.FIELD_HCENTER
																					| Field.NON_FOCUSABLE);
			lbl_header.setFont(parent.getFont().getFontFamily().getFont(Font.ITALIC, UIKeys.DEFAULT_FONT_SIZE));
			fields[i] = lbl_header;
		}

		return fields;
	}

	/**
	 * Obtiene la fuente utilizada en el parametro screen y la devuelve pero en el tama�o que indicamos mediante el
	 * parametro fontSize
	 *
	 * @param screen
	 * @param fontSize El tamaño de la fuente que quiero obtener.
	 *
	 * @return
	 */
	public static Font getFontAtSize(MainScreen screen, int fontSize) {
		if (screen == null)
			return null;

		return screen.getFont().getFontFamily().getFont(Font.PLAIN, fontSize);
	}

	/**
	 * Retorna una nueva fuente con el tamaño especificado en fontSize, a partir de la fuente que le pasamos en aFont
	 *
	 * @param aFont	La fuente que se va a modificar.
	 * @param fontSize El tamaño de la fuente que quiero obtener.
	 *
	 * @return
	 */
	public static Font getFontAtSize(Font aFont, int fontSize) {
		if (aFont == null)
			return null;

		return aFont.getFontFamily().getFont(Font.PLAIN, fontSize);
	}

	/**
	 * @param fields
	 * @param iFontSize
	 *
	 * @return
	 */
	public static Field[] setFontSize(Field[] fields, int iFontSize) {
		if (fields == null)
			return null;

		for (int idx = 0; idx < fields.length; idx++)
			fields[idx].setFont(getFontAtSize(fields[idx].getFont(), iFontSize));

		return fields;
	}

	/**
	 * Inserta una linea en blanco en la screen que le pasamos como parametro.
	 *
	 * @param aScreen
	 *
	 * @return false cuando aScreen sea null. true cuando se pueda agregar la linea OK.
	 */
	public static boolean addNewEmptyLine(MainScreen aScreen) {
		if (aScreen == null)
			return false;

		aScreen.add(new LabelField("")); /* It's an empty line */
		return true;
	}

	/** @return Retorna un Field que deja un renglon en blanco. */
	public static Field getEmptyLine() {
		return new LabelField(""); /* It's an empty line */
	}

	/**
	 * @return Un Field que deja un renglon en blanco, y que a la vez utiliza el maximo disponible de pantalla. Es decir,
	 *         utiliza el maximo del dispositivo entonces redimensiona el tama�o de su padre.
	 */
	public static GridFieldManager getEmptyLineForResize() {
		GridFieldManager aGrid = new GridFieldManager(1, 0);
		aGrid.add(new LabelField());
		return aGrid;
	}

	/**
	 * @param numberOfLines Las N lineas que queremos dejar en blanco.
	 *
	 * @return un Field que deja numberOfLines renglon en blanco, y que a la vez utiliza el maximo disponible de pantalla.
	 *         Es decir, utiliza el maximo del dispositivo entonces redimensiona el tama�o de su padre.
	 */
	public static GridFieldManager getEmptyLineForResize(int numberOfLines) {
		GridFieldManager aGrid = new GridFieldManager(1, 0);
		for (int idx = 0; idx < numberOfLines; idx++)
			aGrid.add(new LabelField());

		return aGrid;
	}

	// /**
	// * @param numberOfLines La cantidad de renglones en blanco que queremos
	// dejar.
	// * @return Retorna un Field[] que deja numberOfLines renglones en blanco.
	// */
	// public static Field[] getEmptyLine(int numberOfLines){
	// Field[] fields= new Field[numberOfLines];
	//
	// for (int idx = 0; idx < numberOfLines; idx++)
	// fields[idx]= new LabelField(""); /* It's an empty line */
	//
	// return fields;
	// }

	/**
	 * Inserta numberOfLines lineas en blanco en la screen que le pasamos como parametro.
	 *
	 * @param aScreen
	 * @param numberOfLines
	 *
	 * @return false cuando aScreen sea null, o numberOfLines sea menor o igual a cero. true cuando se pueda agregar la
	 *         linea OK.
	 */
	public static boolean addNewEmptyLine(Manager aScreen, int numberOfLines) {
		if (aScreen == null || numberOfLines <= 0)
			return false;

		for (int idx = 0; idx < numberOfLines; idx++)
			aScreen.add(new LabelField("")); /* It's an empty line */
		return true;
	}

	/**
	 * Agrega un boton de volver a la screen aScreen que le pasamos como parametro.
	 *
	 * @param aScreen
	 *
	 * @return
	 */
	public static boolean addBackButton(final MainScreen aScreen) {
		if (aScreen == null)
			return false;

		ButtonField bf_back = new ButtonField(BasicUIKeys.LABEL_BACK, Field.FIELD_RIGHT);
		bf_back.setChangeListener(new FieldChangeListener() {
			public void fieldChanged(Field field, int context) {
				UiApplication.getUiApplication().popScreen(aScreen);
			}
		});

		aScreen.add(bf_back);

		return true;
	}

	/**
	 * Prepara la informacion contenida en el Vector data (cada elemento del vector es a su vez un vector que se mapearia
	 * con cada columna de la tabla que queremos generar. Este vector contiene los N elementos Field listos para mostrar en
	 * la tabla.
	 *
	 * @param data
	 * @param numberOfColumns
	 *
	 * @return
	 */
	public static Vector prepareDataForTable(Vector data, int numberOfColumns) {

		Vector[] columns = new Vector[numberOfColumns];
		for (int i = 0; i < numberOfColumns; i++)
			columns[i] = new Vector();

		Enumeration elements = data.elements();
		while (elements.hasMoreElements()) {

			Field[] aRow = (Field[]) elements.nextElement();

			for (int i = 0; i < numberOfColumns; i++) {
				((Vector) columns[i]).addElement(aRow[i]);
			}

		}

		Vector ret = new Vector();
		for (int i = 0; i < numberOfColumns; i++) {
			ret.addElement((Vector) columns[i]);
		}

		return ret;
	}

}
